# Makefile for MLinux Minimal

# Bug fix.
PWD ?= $(shell pwd)

# Dependencies for building.
CC := @CC@
CP := @CP@
CHMOD := @CHMOD@
CPIO := @CPIO@
FIND := @FIND@
MKDIR := @MKDIR@
MKFS := @MKFS@
MOUNT := @MOUNT@
PATCH := @PATCH@
QEMU_IMG := @QEMU_IMG@
RM := @RM@
SED := @SED@
SUDO := @SUDO@
SYSLINUX := @SYSLINUX@
TAR := @TAR@
UMOUNT := @UMOUNT@
WGET := @WGET@
XZ := @XZ@

CREATE_IMAGE = $(QEMU_IMG) create -f raw $(IMAGE_FILE) $(IMAGE_SIZE)

# Configuration.
ARCH ?= x86_64
BUSYBOX = busybox-@BUSYBOX_VERSION@
BUSYBOX_CONFIG = busybox.$(ARCH).config
FS_DIR = fs
IMAGE_FILE = disk.img
IMAGE_SIZE = 6.1M
INITRD_FILE = initrd.cpio
KERNEL = vmlinuz
LINUX = linux-@LINUX_VERSION@
LINUX_CONFIG = linux.$(ARCH).config
LINUX_VERSION_MAJOR = @LINUX_VERSION_MAJOR@
KERNEL_IMAGE = $(LINUX)/arch/$(ARCH)/boot/bzImage
UCLIBC = uClibc-@UCLIBC_VERSION@
UCLIBC_SPECS = uclibc.specs
UCLIBC_CC = $(CC) -specs "$(PWD)/$(UCLIBC_SPECS)" -fno-stack-protector
UCLIBC_CONFIG = uclibc.$(ARCH).config
ROOTFS = rootfs
SYSLINUX_CFG = syslinux.config

# Dependencies for testing.
DU := du

# Mirrors.
include mirrors.mk
BUSYBOX_URL = $(BUSYBOX_MIRROR)/$(BUSYBOX).tar.bz2
LINUX_URL = $(LINUX_MIRROR)/v$(LINUX_VERSION_MAJOR).x/$(LINUX).tar.xz
UCLIBC_URL = $(UCLIBC_MIRROR)/$(UCLIBC).tar.xz

ifneq (,)
This makefile requires GNU Make.
endif

.PHONY : clean totally-clean check

all : $(ROOTFS).tar.xz $(KERNEL).xz $(IMAGE_FILE).xz

$(UCLIBC).tar.xz : 
	$(WGET) "$(UCLIBC_URL)" -O $@

$(UCLIBC) : $(UCLIBC).tar.xz
	@echo "Extracting $@ ..."
	$(TAR) -xf $^

uclibc : $(UCLIBC) $(LINUX)
	$(MKDIR) -p $@
	$(CP) $(UCLIBC_CONFIG) "$(UCLIBC)/.config"
	cd $(LINUX) && CC=false $(MAKE) ARCH=$(ARCH) "INSTALL_HDR_PATH=$(PWD)/$@" headers_install
	$(SED) -i 's|@KERNEL_HEADERS@|$(PWD)/$@/include|g' "$(UCLIBC)/.config"
	cd $(UCLIBC) && $(MAKE) all
	cd $(UCLIBC) && $(MAKE) install PREFIX="$(PWD)/$@"

$(BUSYBOX).tar.bz2 :
	$(WGET) "$(BUSYBOX_URL)" -O $@

$(BUSYBOX) : $(BUSYBOX).tar.bz2
	@echo "Extracting $@ ..."
	$(TAR) -xf $^
	$(CP) -f bb-patches/init.c "$@/init/init.c"
	$(PATCH) -p1 "$@/shell/hush.c" < bb-patches/hush.c.patch
	$(PATCH) -p1 "$@/shell/match.c" < bb-patches/match.c.patch

$(BUSYBOX)/busybox : $(BUSYBOX) $(BUSYBOX_CONFIG) uclibc
	$(CP) $(BUSYBOX_CONFIG) "$(BUSYBOX)/.config"
	cd $(BUSYBOX) && $(MAKE) all CC="$(UCLIBC_CC)"

$(ROOTFS) : $(BUSYBOX)/busybox
	$(MKDIR) -p $(ROOTFS)

	cd $(BUSYBOX) && $(MAKE) install CONFIG_PREFIX="$(PWD)/$@" CC="$(UCLIBC_CC)"

	cd $(ROOTFS) && $(MKDIR) -p dev

$(ROOTFS).tar.xz : $(ROOTFS)
	$(TAR) -c -v -f $(ROOTFS).tar $^
	$(XZ) -z -c -9 $(ROOTFS).tar > $@

$(INITRD_FILE) : $(ROOTFS)
	cd $(ROOTFS) && $(FIND) . | $(CPIO) -H newc -o -v --owner root:root > "$(PWD)/$@"

$(LINUX).tar.xz :
	$(WGET) "$(LINUX_URL)" -O $@

$(LINUX) : $(LINUX).tar.xz
	@echo "Extracting $@ ..."
	$(TAR) -xf $^

$(KERNEL_IMAGE) : $(LINUX) $(LINUX_CONFIG) $(INITRD_FILE)
	$(CP) $(LINUX_CONFIG) "$(LINUX)/.config"
	cd $(LINUX) && $(MAKE) all CC="$(UCLIBC_CC)"

$(KERNEL) : $(KERNEL_IMAGE)
	$(CP) $^ $@
	$(CHMOD) +x $@

$(KERNEL).xz : $(KERNEL)
	$(XZ) -z -c -9 $^ > $@

$(IMAGE_FILE) : $(KERNEL) $(SYSLINUX_CFG)
	$(CREATE_IMAGE)
	$(MKFS) $(IMAGE_FILE)
	$(MKDIR) -p $(FS_DIR)
	$(SUDO) $(MOUNT) $(IMAGE_FILE) $(FS_DIR)
	$(SUDO) $(CP) -f $(KERNEL) "$(FS_DIR)/$(KERNEL)"
	$(SUDO) $(CP) -f $(SYSLINUX_CFG) "$(FS_DIR)/syslinux.cfg"
	$(SUDO) $(UMOUNT) $(FS_DIR)
	$(SYSLINUX) --install $(IMAGE_FILE)

$(IMAGE_FILE).xz : $(IMAGE_FILE)
	$(XZ) -z -c -9 $^ > $@

clean :
	$(RM) -r -f $(UCLIBC)
	$(RM) -r -f uclibc
	$(RM) -r -f $(BUSYBOX)
	$(RM) -r -f $(LINUX)
	$(RM) -r -f $(ROOTFS)
	$(RM) -f $(ROOTFS).tar
	$(RM) -f $(ROOTFS).tar.xz
	$(RM) -f $(INITRD_FILE)
	$(RM) -f $(KERNEL)
	$(RM) -f $(KERNEL).xz
	$(RM) -f $(IMAGE_FILE)
	$(RM) -f $(IMAGE_FILE).xz

totally-clean : clean
	$(RM) -f $(UCLIBC_SPECS)
	$(RM) -f $(BUSYBOX).tar.bz2
	$(RM) -f $(LINUX).tar.xz

check : all
	@echo "BUSYBOX: $(BUSYBOX)"
	$(SUDO) $(DU) -sh $(ROOTFS).tar.xz $(IMAGE_FILE).xz
	cd $(BUSYBOX) && $(MAKE) check
